﻿using Microsoft.AspNetCore.Mvc.RazorPages;
using Newtonsoft.Json;
using System.Text;

namespace OAuth2.Pages
{
    public class PrivacyModel : PageModel
    {
        private readonly ILogger<PrivacyModel> _logger;

        public PrivacyModel(ILogger<PrivacyModel> logger)
        {
            _logger = logger;
        }

        private const string client_id = "43e21bdfe93a542a8af3e44396cbe39ef0c9318c4c0bc640c354a16a7372347e";

        //回调地址进行URL编码。否则请求会出错
        private string redirect_uri = System.Web.HttpUtility.UrlEncode("http://localhost:5092/Privacy");

        private string client_secret = "e6be78689cd05f802423ce807b818d015c53a0d36f9b167f138172b638815995";

        public void OnGet()
        {
            //2.用户对应用进行授权
            var url = $"https://gitee.com/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type=code&scope=user_info%20projects%20pull_requests";
            Console.WriteLine(url);
            Redirect(url);

            //3.获取授权码
            var code = HttpContext.Request.Query["code"];
            Console.WriteLine(code);

            //4.获取access_token
            var token = GetAccessToken(code);
            var accessToken = JsonConvert.DeserializeObject<AccessToken>(token);
            ViewData["Token"] = accessToken.access_token;
            var user = GetUser(accessToken.access_token);
            ViewData["User"] = user;

            var newToken = RefreshToken(accessToken.refresh_token);
            var newAccessToken = JsonConvert.DeserializeObject<AccessToken>(newToken);
            ViewData["NewToken"] = newAccessToken.access_token;
        }

        /// <summary>
        /// 4.获取access_token(密码模式)
        /// </summary>
        /// <param name="userName">账号</param>
        /// <param name="password">密码</param>
        /// <returns>Token</returns>
        private string GetAccessToken(string userName,string password) 
        {
            using (HttpClient client = new HttpClient())
            {
                string url = "https://gitee.com/oauth/token";
                string data = $"grant_type=password&username={userName}&password={password}&client_id={client_id}&client_secret={client_secret}&scope=projects user_info issues notes";

                StringContent content = new StringContent(data, System.Text.Encoding.UTF8, "application/x-www-form-urlencoded");

                HttpResponseMessage response = client.PostAsync(url, content).Result;

                if (response.IsSuccessStatusCode)
                {
                    string responseContent = response.Content.ReadAsStringAsync().Result;
                    Console.WriteLine("Response: " + responseContent);
                    return responseContent;
                }
                else
                {
                    Console.WriteLine("Error: " + response.StatusCode);
                    return "Error Request";
                }
            }
        }

        /// <summary>
        /// 4.获取access_token
        /// </summary>
        /// <param name="code">授权码</param>
        /// <returns>Token</returns>
        private string GetAccessToken(string code) 
        {
            var url = $"https://gitee.com/oauth/token?grant_type=authorization_code&code={code}&client_id={client_id}&redirect_uri={redirect_uri}&client_secret={client_secret}";
            using (HttpClient client = new HttpClient())
            {
                string jsonData = "{\"key\": \""+ client_secret + "\"}"; // 要发送的 JSON 数据
                StringContent content = new StringContent(jsonData, Encoding.UTF8, "application/json");

                HttpResponseMessage response = client.PostAsync(url, content).Result;

                if (response.IsSuccessStatusCode)
                {
                    string responseContent = response.Content.ReadAsStringAsync().Result;
                    Console.WriteLine("Response: " + responseContent);
                    return responseContent;
                }
                else
                {
                    Console.WriteLine("Error: " + response.StatusCode);
                    return "Error Request";
                }
            }
        }

        /// <summary>
        /// 5.使用Token调用获取用户信息API
        /// </summary>
        /// <param name="token">token</param>
        /// <returns>用户信息</returns>
        private string GetUser(string token) 
        {
            var url = $"https://gitee.com/api/v5/user?access_token={token}";
            using (HttpClient client = new HttpClient())
            {
                HttpResponseMessage response = client.GetAsync(url).Result;

                if (response.IsSuccessStatusCode)
                {
                    string responseContent = response.Content.ReadAsStringAsync().Result;
                    Console.WriteLine("Response: " + responseContent);
                    return responseContent;
                }
                else
                {
                    Console.WriteLine("Error: " + response.StatusCode);
                    return "Error Request";
                }
            }
        }

        /// <summary>
        /// 当 access_token过期后（有效期为一天)通过refresh_token重新获取access_token
        /// </summary>
        /// <param name="refreshToken">刷新token凭据</param>
        /// <returns>刷新后的Token</returns>
        public string RefreshToken(string refreshToken)
        {
            var url = $"https://gitee.com/oauth/token?grant_type=refresh_token&refresh_token={refreshToken}";
            using (HttpClient client = new HttpClient())
            {
                string jsonData = "{\"key\": \"" + client_secret + "\"}"; // 要发送的 JSON 数据
                StringContent content = new StringContent(jsonData, Encoding.UTF8, "application/json");

                HttpResponseMessage response = client.PostAsync(url, content).Result;

                if (response.IsSuccessStatusCode)
                {
                    string responseContent = response.Content.ReadAsStringAsync().Result;
                    Console.WriteLine("Response: " + responseContent);
                    return responseContent;
                }
                else
                {
                    Console.WriteLine("Error: " + response.StatusCode);
                    return "Error Request";
                }
            }
        }
    }

}
